<template>
  <div>
    <div class="cropper-content">
      
      <!-- 剪裁框 -->
      <div class="cropper">
        <img ref="image" :src="imgdata" crossorigin="anonymous" />
      </div>
      <!-- 预览框 -->
      <div
        class="show-preview"
        :style="{
          overflow: 'hidden',
          margin: '0 25px',
          display: 'flex',
          'align-items': 'center'
        }"
      >
        <div class="preview before" />
      </div>
    </div>
    <div class="footer-btn">
      <!-- 缩放旋转按钮 -->
      <div class="scope-btn">
        <el-tooltip class="item" effect="dark" content="放大" placement="top">
          <el-button icon="el-icon-zoom-in" @click="cropperzoom(0.05)" />
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="缩小" placement="top">
          <el-button icon="el-icon-zoom-out" @click="cropperzoom(-0.05)" />
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="逆时针旋转" placement="top">
          <el-button icon="el-icon-refresh-left" @click="cropperRotate(-90)" />
        </el-tooltip>
        <el-tooltip class="item" effect="dark" content="顺时针旋转" placement="top">
          <el-button icon="el-icon-refresh-right" @click="cropperRotate(90)" />
        </el-tooltip>
      </div>

      <!-- 确认上传按钮 -->
      <div class="upload-btn">
        <!-- <el-button type="primary" @click="uploadImg('blob')">{{ $t('common.upload') }}</el-button> -->
        <el-button @click="closeCropper">{{ $t('common.cancel') }}</el-button>
        <el-button type="primary" :disabled="isDisabled" @click="sureSava()">{{ $t('common.confirm') }}</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'

export default {
  name: 'VueCropper',
  props: {
    autoCropWidth: {
      type: Number,
      default: 0
    },
    autoCropHeight: {
      type: Number,
      default: 0
    },
    aspectRatio: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      myCropper: null,
      afterImg: '',
      ScaleX: 1,
      ScaleY: 1,
      fixed: false,
      fixedBox: false,
      inputRotate: 0,
      isDisabled: false,
      imgdata: ''
    }
  },
  destroyed() {
    this.myCropper && this.myCropper.destroy()
  },
  methods: {
    setData(file) {
      this.imgdata = file
      this.$nextTick(() => {
        this.init()
      })
    },
    closeCropper() {
      this.$emit('closeCropper')
    },
    handleChangeRotate(value) {
      this.cropperrotateTo(value)
    },
    init() {
      this.myCropper = new Cropper(this.$refs.image, {
        viewMode: 1,
        dragMode: 'move',
        // initialAspectRatio: 1,
        preview: '.before',
        background: false,
        autoCropArea: 1,
        zoomOnWheel: true,
        aspectRatio: this.aspectRatio,
        outputType: 'png'
        // movable :true,
        // rotatable :true
      })
    },
    // 裁剪
    uploadImgs() {
      this.afterImg = this.myCropper
        .getCroppedCanvas({
          imageSmoothingQuality: 'high'
        })
        .toDataURL('image/jpeg')
      this.$emit('getCrop', this.afterImg)
    },
    sureSava() {
      this.afterImg = this.myCropper
        .getCroppedCanvas({
          imageSmoothingQuality: 'high'
        })
        .toDataURL('image/jpeg')
        // console.log(this.afterImg)
        this.transformFile(this.afterImg).then(r => {
          this.$emit('upload', this.dataURLtoFile(this.afterImg))
        })
        // console.log(this.dataURLtoFile(this.afterImg))
      // this.$emit('upload', this.dataURLtoFile(this.afterImg))
    },
    transformFile(base64) {
      //promise执行多步操作非常好用，这个过程是有一定的顺序的，你必须保证上一步完成，才能顺利进行下一步。
      //有两个参数 resolve同意的意思 reject拒绝的意思
      return new Promise(resolve => {
         const canvas = document.createElement('canvas') //新建canvas 画布
          const img = document.createElement('img') //新建一个img标签
          img.src = base64 //读取结果 下载图片
          img.onload = () => {
            //绑定事件 下载完成
            const ctx = canvas.getContext('2d') //获取画笔对象
            let width = img.width //图片的宽高
            let height = img.height
            canvas.width = width //画布的宽高
            canvas.height = height
            ctx.drawImage(img, 0, 0, width, height) //绘制图像 图片大小没变
            ctx.fillStyle = '#000' // 设置填充字号和字体，样式
            // ctx.textBaseline = 'middle'
            // // 设置右对齐
            // ctx.textAlign = 'right'
            // // ctx.rotate((0 * Math.PI) / 180) //旋转画笔 角度
            ctx.globalAlpha = 0.3 //透明度
            ctx.font = '12px'
            ctx.fillText('powered by Jihepai', 0, height - 2, width)
            /* canvas.toBlob(resolve); */
            //压缩图片质量 范围 0~1
            let dataUrl = canvas.toDataURL('image/jpeg', 1) //输出压缩后的base64
            //执行下一步操作 将裁剪base64的图片转换为file文件
            // resolve(this.dataURLtoFile(dataUrl, file.name))
            resolve(dataUrl)
          }
      })
    },
    // 将裁剪base64的图片转换为file文件
    dataURLtoFile(dataurl, filename) {
      let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    },
    base64ToBlob(code) {
      const parts = code.split(';base64,')
      const contentType = parts[0].split(':')[1]
      const raw = window.atob(parts[1])
      const rawLength = raw.length

      const uInt8Array = new Uint8Array(rawLength)

      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      return new Blob([uInt8Array], {
        type: contentType
      })
    },
    dataURLtoFile(dataurl, filename = 'file') {
      var arr = dataurl.split(',')
      var mime = arr[0].match(/:(.*?);/)[1]
      var suffix = mime.split('/')[1]
      var bstr = atob(arr[1])
      let n = bstr.length
      var u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], `${filename}.${suffix}`, { type: mime })
    },
    // 缩放
    cropperzoom(val) {
      this.myCropper.zoom(val)
    },
    // 重置
    cropperReset() {
      this.myCropper.reset()
      this.ScaleX = 1
      this.ScaleY = 1
    },
    // 移动
    croppermove(val1, val2) {
      this.myCropper.move(val1, val2)
    },
    // 旋转
    cropperRotate(val) {
      this.myCropper.rotate(val)
    },
    // 绝对角度旋转
    cropperrotateTo(val) {
      this.myCropper.rotateTo(val)
    },
    // X轴翻转
    cropperScaleX() {
      this.ScaleX = -this.ScaleX
      if (this.myCropper.getImageData().rotate === -90 || this.myCropper.getImageData().rotate === 90) {
        this.myCropper.scaleY(this.ScaleX)
      } else {
        this.myCropper.scaleX(this.ScaleX)
      }
    },
    // y轴翻转
    cropperScaleY() {
      // console.log(this.myCropper.getImageData().rotate)
      this.ScaleY = -this.ScaleY
      if (this.myCropper.getImageData().rotate === -90 || this.myCropper.getImageData().rotate === 90) {
        this.myCropper.scaleX(this.ScaleY)
      } else {
        this.myCropper.scaleY(this.ScaleY)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.cropper {
  border: 1px solid #fff;
  background-image: url();
  img {
    width: 100%;
    opacity: 0;
  }
}
.cropper-content {
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.cropper-content .cropper {
  width: 550px;
  height: 400px;
  overflow: hidden;
}
.cropper-content .show-preview {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: center;
  -webkit-justify-content: center;
  overflow: hidden;
  /* border: 1px solid #cccccc; */
  background: #cccccc;
  margin-left: 40px;
}
.preview {
  overflow: hidden;
  border: 1px solid #468ac8;
  background: #cccccc;
}
.footer-btn {
  margin-top: 30px;
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
}
.footer-btn .scope-btn {
  width: 260px;
  display: flex;
  display: -webkit-flex;
  justify-content: space-between;
  -webkit-justify-content: space-between;
}
.footer-btn .scope-btn span {
  display: inline-block;
  padding: 10px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-radius: 5px;
  background: #fff;
  cursor: pointer;
}
.footer-btn .scope-btn span i {
  font-size: 32px;
  color: #333333;
}
.footer-btn .upload-btn {
  flex: 1;
  -webkit-flex: 1;
  display: flex;
  display: -webkit-flex;
  justify-content: flex-end;
  -webkit-justify-content: flex-end;
  margin-right: 25px;
}
.footer-btn .btn {
  outline: none;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  outline: 0;
  margin: 0;
  -webkit-transition: 0.1s;
  transition: 0.1s;
  font-weight: 500;
  padding: 8px 15px;
  font-size: 12px;
  border-radius: 3px;
  color: #fff;
  background-color: #67c23a;
  border-color: #67c23a;
}
.solide {
  margin-left: 25px;
  width: 200px;
}
.before {
  width: 100%;
  height: 100%;
  overflow: hidden;
  /* 这个属性可以得到想要的效果 */
}
</style>
